#include "Window.h"
#include <GLFW/glfw3.h>
#include <unistd.h>

USE_JLIB_NS


Window::Window () {
  initialize();
}

Window::~Window () {
}


void Window::createWindow (int w, int h, const char* name) {
  _window = glfwCreateWindow(w, h, "jlib-graphics-test", nullptr, nullptr);
  __windows.emplace(_window, this);
  glfwMakeContextCurrent(_window);

  glfwSetWindowPosCallback(_window, &onWindowPos);
  glfwSetWindowSizeCallback(_window, &onWindowSize);
  glfwSetWindowCloseCallback(_window, &onWindowClose);
  glfwSetWindowFocusCallback(_window, &onWindowFocus);
  glfwSetWindowIconifyCallback(_window, &onWindowIconify);
  glfwSetFramebufferSizeCallback(_window, &onFramebufferSize);
  glfwSetMouseButtonCallback(_window, &onMouseButton);
  glfwSetCursorPosCallback(_window, &onCursorPos);
  glfwSetCursorEnterCallback(_window, &onCursorEnter);
  glfwSetScrollCallback(_window, &onScroll);
  glfwSetKeyCallback(_window, &onKey);
  glfwSetCharCallback(_window, &onChar);
}

void Window::destroyWindow () {
  glfwSetWindowPosCallback(_window, nullptr);
  glfwSetWindowSizeCallback(_window, nullptr);
  glfwSetWindowCloseCallback(_window, nullptr);
  glfwSetWindowFocusCallback(_window, nullptr);
  glfwSetWindowIconifyCallback(_window, nullptr);
  glfwSetFramebufferSizeCallback(_window, nullptr);
  glfwSetMouseButtonCallback(_window, nullptr);
  glfwSetCursorPosCallback(_window, nullptr);
  glfwSetCursorEnterCallback(_window, nullptr);
  glfwSetScrollCallback(_window, nullptr);
  glfwSetKeyCallback(_window, nullptr);
  glfwSetCharCallback(_window, nullptr);

  __windows.erase(_window);
  glfwDestroyWindow(_window);
}

void Window::show (int w, int h, const char* name) {
  createWindow(w, h, name);
  glfwGetFramebufferSize(_window, &_w, &_h);
  abort_assert(glewInit() == GLEW_OK);
  _root = initRootNode();
  abort_assert(_root);
  _root->resize(_w, _h);

  static const auto FrameInterval = (s64)round(1000000.0 / 60.0);
  auto prevTime = Date::currentMicroseconds();
  while (!glfwWindowShouldClose(_window)) {
    glfwPollEvents();
    _root->mainLoop();
    glfwSwapBuffers(_window);
    ObjCache::gflush();
    auto nextTime = prevTime + FrameInterval;
    auto idleTime = nextTime - Date::currentMicroseconds();
    if (idleTime > 10)
      usleep((u32)idleTime);
    prevTime = Date::currentMicroseconds();
  }
  _root = nullptr;
  ObjCache::gflush();
  destroyWindow();
}





void Window::initialize () {
  if (__glfwInitialized)
    return;
  glfwSetErrorCallback(&onError);
  abort_assert(glfwInit() == GL_TRUE);
  glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
  glfwWindowHint(GLFW_RED_BITS, 8);
  glfwWindowHint(GLFW_GREEN_BITS, 8);
  glfwWindowHint(GLFW_BLUE_BITS, 8);
  glfwWindowHint(GLFW_ALPHA_BITS, 8);
  glfwWindowHint(GLFW_DEPTH_BITS, 24);
  glfwWindowHint(GLFW_STENCIL_BITS, 8);
  glfwWindowHint(GLFW_SAMPLES, 8);
}

<<<<<<< HEAD
=======
void Window::onError (int error, const char* description) {
  log_e("GLFW Error(%d): %s", error, description);
}

void Window::onWindowPos (GLFWwindow* window, int xpos, int ypos) {
}

void Window::onWindowSize (GLFWwindow* window, int width, int height) {
}

void Window::onWindowClose (GLFWwindow* window) {
}

void Window::onWindowFocus (GLFWwindow* window, int focused) {
}

void Window::onWindowIconify (GLFWwindow* window, int iconified) {
}

void Window::onFramebufferSize (GLFWwindow* window, int width, int height) {
  glfwMakeContextCurrent(window);
  auto iter = __windows.find(window);
  auto view = iter->second;
  auto root = view->_root;
  auto oldWidth = view->_w;
  auto oldHeight = view->_h;
  root->resize(oldWidth, oldHeight, width, height);
  view->_w = width;
  view->_h = height;
}

void Window::onMouseButton (GLFWwindow* window, int button, int action, int mods) {
  glfwMakeContextCurrent(window);

  button = 1 << button;
  auto iter = __windows.find(window);
  auto view = iter->second;
  auto root = view->_root;
  if (action == GLFW_PRESS)
    root->dispatchMouseDown(button, view->_lastPointerLocation);
  else if (action == GLFW_RELEASE)
    root->dispatchMouseUp(button, view->_lastPointerLocation);
}

void Window::onCursorPos (GLFWwindow* window, double xpos, double ypos) {
  glfwMakeContextCurrent(window);
  auto iter = __windows.find(window);
  auto view = iter->second;
  auto root = view->_root;
  view->_lastPointerLocation = vec2(xpos, view->_h - ypos);
  root->dispatchMouseMove(view->_lastPointerLocation);
}

void Window::onCursorEnter (GLFWwindow* window, int entered) {
  if (entered)
    return;
  glfwMakeContextCurrent(window);
  auto iter = __windows.find(window);
  auto view = iter->second;
  auto root = view->_root;
  root->dispatchMouseLeave();
}

void Window::onScroll (GLFWwindow* window, double xoffset, double yoffset) {
  glfwMakeContextCurrent(window);
  auto iter = __windows.find(window);
  auto view = iter->second;
  auto root = view->_root;
  root->dispatchWheelScroll((int)yoffset, view->_lastPointerLocation);
}

void Window::onKey (GLFWwindow *window, int key, int scancode, int action, int mods) {
  glfwMakeContextCurrent(window);
  auto iter = __windows.find(window);
  auto view = iter->second;
  auto root = view->_root;
  auto code = __keyMapping[key];
  if (code == KeyCode::Unknown)
    return;
  if (action == GLFW_PRESS)
    root->dispatchKeyDown(code);
  else if (action == GLFW_RELEASE)
    root->dispatchKeyUp(code);
}

void Window::onChar (GLFWwindow *window, unsigned int codepoint) {
}
>>>>>>> 2abca45f566c85c75552c8cff55aa877f0fc6380




bool Window::__glfwInitialized = false;

<<<<<<< HEAD
=======
KeyCode Window::__keyMapping[] = {
  KeyCode::Unknown, // 0
  KeyCode::Unknown, // 1
  KeyCode::Unknown, // 2
  KeyCode::Unknown, // 3
  KeyCode::Unknown, // 4
  KeyCode::Unknown, // 5
  KeyCode::Unknown, // 6
  KeyCode::Unknown, // 7
  KeyCode::Unknown, // 8
  KeyCode::Unknown, // 9
  KeyCode::Unknown, // 10
  KeyCode::Unknown, // 11
  KeyCode::Unknown, // 12
  KeyCode::Unknown, // 13
  KeyCode::Unknown, // 14
  KeyCode::Unknown, // 15
  KeyCode::Unknown, // 16
  KeyCode::Unknown, // 17
  KeyCode::Unknown, // 18
  KeyCode::Unknown, // 19
  KeyCode::Unknown, // 20
  KeyCode::Unknown, // 21
  KeyCode::Unknown, // 22
  KeyCode::Unknown, // 23
  KeyCode::Unknown, // 24
  KeyCode::Unknown, // 25
  KeyCode::Unknown, // 26
  KeyCode::Unknown, // 27
  KeyCode::Unknown, // 28
  KeyCode::Unknown, // 29
  KeyCode::Unknown, // 30
  KeyCode::Unknown, // 31
  KeyCode::Space, // 32
  KeyCode::Unknown, // 33
  KeyCode::Unknown, // 34
  KeyCode::Unknown, // 35
  KeyCode::Unknown, // 36
  KeyCode::Unknown, // 37
  KeyCode::Unknown, // 38
  KeyCode::CloseQuotation, // 39
  KeyCode::Unknown, // 40
  KeyCode::Unknown, // 41
  KeyCode::Unknown, // 42
  KeyCode::Unknown, // 43
  KeyCode::Comma, // 44
  KeyCode::Minus, // 45
  KeyCode::Period, // 46
  KeyCode::Slash, // 47
  KeyCode::_0, // 48
  KeyCode::_1, // 49
  KeyCode::_2, // 50
  KeyCode::_3, // 51
  KeyCode::_4, // 52
  KeyCode::_5, // 53
  KeyCode::_6, // 54
  KeyCode::_7, // 55
  KeyCode::_8, // 56
  KeyCode::_9, // 57
  KeyCode::Unknown, // 58
  KeyCode::Semicolon, // 59
  KeyCode::Unknown, // 60
  KeyCode::Equal, // 61
  KeyCode::Unknown, // 62
  KeyCode::Unknown, // 63
  KeyCode::Unknown, // 64
  KeyCode::A, // 65
  KeyCode::B, // 66
  KeyCode::C, // 67
  KeyCode::D, // 68
  KeyCode::E, // 69
  KeyCode::F, // 70
  KeyCode::G, // 71
  KeyCode::H, // 72
  KeyCode::I, // 73
  KeyCode::J, // 74
  KeyCode::K, // 75
  KeyCode::L, // 76
  KeyCode::M, // 77
  KeyCode::N, // 78
  KeyCode::O, // 79
  KeyCode::P, // 80
  KeyCode::Q, // 81
  KeyCode::R, // 82
  KeyCode::S, // 83
  KeyCode::T, // 84
  KeyCode::U, // 85
  KeyCode::V, // 86
  KeyCode::W, // 87
  KeyCode::X, // 88
  KeyCode::Y, // 89
  KeyCode::Z, // 90
  KeyCode::BracketLeft, // 91
  KeyCode::BackSlash, // 92
  KeyCode::BracketRight, // 93
  KeyCode::Unknown, // 94
  KeyCode::Unknown, // 95
  KeyCode::OpenQuotation, // 96
  KeyCode::Unknown, // 97
  KeyCode::Unknown, // 98
  KeyCode::Unknown, // 99
  KeyCode::Unknown, // 100
  KeyCode::Unknown, // 101
  KeyCode::Unknown, // 102
  KeyCode::Unknown, // 103
  KeyCode::Unknown, // 104
  KeyCode::Unknown, // 105
  KeyCode::Unknown, // 106
  KeyCode::Unknown, // 107
  KeyCode::Unknown, // 108
  KeyCode::Unknown, // 109
  KeyCode::Unknown, // 110
  KeyCode::Unknown, // 111
  KeyCode::Unknown, // 112
  KeyCode::Unknown, // 113
  KeyCode::Unknown, // 114
  KeyCode::Unknown, // 115
  KeyCode::Unknown, // 116
  KeyCode::Unknown, // 117
  KeyCode::Unknown, // 118
  KeyCode::Unknown, // 119
  KeyCode::Unknown, // 120
  KeyCode::Unknown, // 121
  KeyCode::Unknown, // 122
  KeyCode::Unknown, // 123
  KeyCode::Unknown, // 124
  KeyCode::Unknown, // 125
  KeyCode::Unknown, // 126
  KeyCode::Unknown, // 127
  KeyCode::Unknown, // 128
  KeyCode::Unknown, // 129
  KeyCode::Unknown, // 130
  KeyCode::Unknown, // 131
  KeyCode::Unknown, // 132
  KeyCode::Unknown, // 133
  KeyCode::Unknown, // 134
  KeyCode::Unknown, // 135
  KeyCode::Unknown, // 136
  KeyCode::Unknown, // 137
  KeyCode::Unknown, // 138
  KeyCode::Unknown, // 139
  KeyCode::Unknown, // 140
  KeyCode::Unknown, // 141
  KeyCode::Unknown, // 142
  KeyCode::Unknown, // 143
  KeyCode::Unknown, // 144
  KeyCode::Unknown, // 145
  KeyCode::Unknown, // 146
  KeyCode::Unknown, // 147
  KeyCode::Unknown, // 148
  KeyCode::Unknown, // 149
  KeyCode::Unknown, // 150
  KeyCode::Unknown, // 151
  KeyCode::Unknown, // 152
  KeyCode::Unknown, // 153
  KeyCode::Unknown, // 154
  KeyCode::Unknown, // 155
  KeyCode::Unknown, // 156
  KeyCode::Unknown, // 157
  KeyCode::Unknown, // 158
  KeyCode::Unknown, // 159
  KeyCode::Unknown, // 160
  KeyCode::Unknown, // 161
  KeyCode::Unknown, // 162
  KeyCode::Unknown, // 163
  KeyCode::Unknown, // 164
  KeyCode::Unknown, // 165
  KeyCode::Unknown, // 166
  KeyCode::Unknown, // 167
  KeyCode::Unknown, // 168
  KeyCode::Unknown, // 169
  KeyCode::Unknown, // 170
  KeyCode::Unknown, // 171
  KeyCode::Unknown, // 172
  KeyCode::Unknown, // 173
  KeyCode::Unknown, // 174
  KeyCode::Unknown, // 175
  KeyCode::Unknown, // 176
  KeyCode::Unknown, // 177
  KeyCode::Unknown, // 178
  KeyCode::Unknown, // 179
  KeyCode::Unknown, // 180
  KeyCode::Unknown, // 181
  KeyCode::Unknown, // 182
  KeyCode::Unknown, // 183
  KeyCode::Unknown, // 184
  KeyCode::Unknown, // 185
  KeyCode::Unknown, // 186
  KeyCode::Unknown, // 187
  KeyCode::Unknown, // 188
  KeyCode::Unknown, // 189
  KeyCode::Unknown, // 190
  KeyCode::Unknown, // 191
  KeyCode::Unknown, // 192
  KeyCode::Unknown, // 193
  KeyCode::Unknown, // 194
  KeyCode::Unknown, // 195
  KeyCode::Unknown, // 196
  KeyCode::Unknown, // 197
  KeyCode::Unknown, // 198
  KeyCode::Unknown, // 199
  KeyCode::Unknown, // 200
  KeyCode::Unknown, // 201
  KeyCode::Unknown, // 202
  KeyCode::Unknown, // 203
  KeyCode::Unknown, // 204
  KeyCode::Unknown, // 205
  KeyCode::Unknown, // 206
  KeyCode::Unknown, // 207
  KeyCode::Unknown, // 208
  KeyCode::Unknown, // 209
  KeyCode::Unknown, // 210
  KeyCode::Unknown, // 211
  KeyCode::Unknown, // 212
  KeyCode::Unknown, // 213
  KeyCode::Unknown, // 214
  KeyCode::Unknown, // 215
  KeyCode::Unknown, // 216
  KeyCode::Unknown, // 217
  KeyCode::Unknown, // 218
  KeyCode::Unknown, // 219
  KeyCode::Unknown, // 220
  KeyCode::Unknown, // 221
  KeyCode::Unknown, // 222
  KeyCode::Unknown, // 223
  KeyCode::Unknown, // 224
  KeyCode::Unknown, // 225
  KeyCode::Unknown, // 226
  KeyCode::Unknown, // 227
  KeyCode::Unknown, // 228
  KeyCode::Unknown, // 229
  KeyCode::Unknown, // 230
  KeyCode::Unknown, // 231
  KeyCode::Unknown, // 232
  KeyCode::Unknown, // 233
  KeyCode::Unknown, // 234
  KeyCode::Unknown, // 235
  KeyCode::Unknown, // 236
  KeyCode::Unknown, // 237
  KeyCode::Unknown, // 238
  KeyCode::Unknown, // 239
  KeyCode::Unknown, // 240
  KeyCode::Unknown, // 241
  KeyCode::Unknown, // 242
  KeyCode::Unknown, // 243
  KeyCode::Unknown, // 244
  KeyCode::Unknown, // 245
  KeyCode::Unknown, // 246
  KeyCode::Unknown, // 247
  KeyCode::Unknown, // 248
  KeyCode::Unknown, // 249
  KeyCode::Unknown, // 250
  KeyCode::Unknown, // 251
  KeyCode::Unknown, // 252
  KeyCode::Unknown, // 253
  KeyCode::Unknown, // 254
  KeyCode::Unknown, // 255
  KeyCode::Esc, // 256
  KeyCode::Enter, // 257
  KeyCode::Tab, // 258
  KeyCode::BackSpace, // 259
  KeyCode::Insert, // 260
  KeyCode::Delete, // 261
  KeyCode::Right, // 262
  KeyCode::Left, // 263
  KeyCode::Down, // 264
  KeyCode::Up, // 265
  KeyCode::PageUp, // 266
  KeyCode::PageDown, // 267
  KeyCode::Home, // 268
  KeyCode::End, // 269
  KeyCode::Unknown, // 270
  KeyCode::Unknown, // 271
  KeyCode::Unknown, // 272
  KeyCode::Unknown, // 273
  KeyCode::Unknown, // 274
  KeyCode::Unknown, // 275
  KeyCode::Unknown, // 276
  KeyCode::Unknown, // 277
  KeyCode::Unknown, // 278
  KeyCode::Unknown, // 279
  KeyCode::CapsLock, // 280
  KeyCode::ScrollLock, // 281
  KeyCode::NumLock, // 282
  KeyCode::Print, // 283
  KeyCode::Pause, // 284
  KeyCode::Unknown, // 285
  KeyCode::Unknown, // 286
  KeyCode::Unknown, // 287
  KeyCode::Unknown, // 288
  KeyCode::Unknown, // 289
  KeyCode::F1, // 290
  KeyCode::F2, // 291
  KeyCode::F3, // 292
  KeyCode::F4, // 293
  KeyCode::F5, // 294
  KeyCode::F6, // 295
  KeyCode::F7, // 296
  KeyCode::F8, // 297
  KeyCode::F9, // 298
  KeyCode::F10, // 299
  KeyCode::F11, // 300
  KeyCode::F12, // 301
  KeyCode::Unknown, // 302
  KeyCode::Unknown, // 303
  KeyCode::Unknown, // 304
  KeyCode::Unknown, // 305
  KeyCode::Unknown, // 306
  KeyCode::Unknown, // 307
  KeyCode::Unknown, // 308
  KeyCode::Unknown, // 309
  KeyCode::Unknown, // 310
  KeyCode::Unknown, // 311
  KeyCode::Unknown, // 312
  KeyCode::Unknown, // 313
  KeyCode::Unknown, // 314
  KeyCode::Unknown, // 315
  KeyCode::Unknown, // 316
  KeyCode::Unknown, // 317
  KeyCode::Unknown, // 318
  KeyCode::Unknown, // 319
  KeyCode::Num0, // 320
  KeyCode::Num1, // 321
  KeyCode::Num2, // 322
  KeyCode::Num3, // 323
  KeyCode::Num4, // 324
  KeyCode::Num5, // 325
  KeyCode::Num6, // 326
  KeyCode::Num7, // 327
  KeyCode::Num8, // 328
  KeyCode::Num9, // 329
  KeyCode::NumDot, // 330
  KeyCode::NumDiv, // 331
  KeyCode::NumMul, // 332
  KeyCode::NumSub, // 333
  KeyCode::NumAdd, // 334
  KeyCode::NumEq, // 335
  KeyCode::NumEq, // 336
  KeyCode::Unknown, // 337
  KeyCode::Unknown, // 338
  KeyCode::Unknown, // 339
  KeyCode::Shift, // 340
  KeyCode::Control, // 341
  KeyCode::Alt, // 342
  KeyCode::Super, // 343
  KeyCode::ShiftRight, // 344
  KeyCode::ControlRight, // 345
  KeyCode::AltRight, // 346
  KeyCode::SuperRight, // 347
  KeyCode::Menu, // 348
};

MouseButton Window::__mouseButtonMapping[] = {
  MouseButton::Left,
  MouseButton::Right,
  MouseButton::Middle,
  MouseButton::Button_4,
  MouseButton::Button_5,
  MouseButton::Button_6,
  MouseButton::Button_7,
  MouseButton::Button_8,
};
>>>>>>> 2abca45f566c85c75552c8cff55aa877f0fc6380


CLOSE_JLIB_NS
